大規模ユーザー辞書向けのインデックス/キャッシュを追加#320
Conversation
|
@artin-kagun |
|
もう少し細かく実装を読んでみたのですが、今のrevision周りの実装はexportを変換のタイミングでやろうとしているのが原因だと思うので、ユーザ辞書を設定し終わったタイミングでexportするようにすることでもっとシンプルにできると思いました。 |
|
ご指摘ありがとうございます。 (※PRのコメントもEditしました) revision管理が複雑になっていた点について、方針を見直しました。以前のcache/revision方式の実装はrevertし、ユーザー辞書の設定を変更したタイミングでcompiled dictionaryをexportし、変換時にはその結果を参照する方式として再実装しました。 force pushで履歴を書き換えるのではなく、既存実装のrevert commitと新方式のcommitを追加する形にしています。 実装としては、ユーザー辞書とシステムユーザー辞書の現在の設定内容から 今回の変更では、ユーザー辞書編集画面での編集完了・削除・取り消し、およびシステムユーザー辞書の読み込み・リセット時にcompiled dictionaryをbackgroundでexportします。初回起動時には、compiled dictionaryがまだ存在しない場合のみ現在の設定内容からexportします。 変換時には、UserDefaults上のユーザー辞書全体を毎回読み出してdynamic dictionaryとして投入する処理をやめ、converterにcompiled dictionaryのURLを渡して参照させます。これにより、辞書が大きい場合でも変換中に全件を組み立て直す処理を避ける意図です。 一方で、compiled dictionaryに含められない読みもあります。そのため、compiled dictionaryに入れられない項目はfallbackとしてJSONに保存し、入力中の読みと関係するものだけdynamic dictionaryとして渡すようにしています。ここでは候補数を上限で切るような処理は入れていないため、変換精度を落とす方向の対応にはしていません。 実行中のIMEが設定変更後のcompiled dictionaryを再読み込みできるように、 また、converter側では ローカルでは、約40,000語規模のユーザー辞書を読み込んだ状態でcompiled dictionaryが作成され、登録語由来の候補が変換候補に出ることを確認しています。 確認したコマンドは以下です。 swift test --disable-sandbox --package-path Core --build-path /private/tmp/azookey-pr320-export-on-save-build --filter UserDictionary
swift test --disable-sandbox --package-path Core --build-path /private/tmp/azookey-pr320-export-on-save-build
git diff --check upstream/main
xcrun swiftc -parse azooKeyMac/AppDelegate.swift azooKeyMac/Windows/ConfigWindow.swift azooKeyMac/Windows/UserDictionaryEditorWindow.swift関連して、#319 ではユーザー辞書のインポート/エクスポート機能も提案していますが、大規模な辞書をインポートできるようにする場合、複数の辞書を分けて管理できると、分野ごとの有効/無効切り替えや辞書単位での整理がしやすくなると考えています。 |
おそらく辞書データに利用できないreadingの存在の話かと思います。確かに、数字・英字・カタカナくらいしかサポートしていないはずです。それ以外を読みとする単語はそもそも入力やimport(別PRですが)のvalidationで弾くようにして、fallbackにJSONを使うのは避けたいです。
確かKanaKanjiConverterインスタンスはIMEアプリケーション全体でシングルトンに近い扱いになっていると思うので、単にそれを経由してuser dictionaryのreloadをトリガーするのがよりシンプルな気がしました。metadata.jsonを不要にできると思います。 一般に、ユーザ環境によく設計されていないファイルを保存していくのは将来的に負債になるので、避けたいです。 |
|
あと、Ubuntu向けのTest / Buildが通っていないので修正お願いします! 🙏 |
|
ご指摘ありがとうございます。 ご指摘いただいた内容に合わせて、fallback JSON と metadata.json を使わない形に整理した修正版を別PRとして出させていただこうと思います。 具体的には、compiled dictionary に含められない読みは fallback JSON に保存せず export 対象から除外し、変換時に fallback JSON を dynamic dictionary として渡す処理も削除しました。また、metadata.json の modificationDate による更新検知はやめ、ユーザー辞書の保存後に共有の KanaKanjiConverter インスタンスへ明示的に reload を通知する形に変更しています。 既存の手動ユーザー辞書UIには読みのvalidationがないため、このPRではUI仕様変更までは行わず、入力時・import時のvalidationについては import 機能側のPRで扱う想定です。 Ubuntu CIについては、主要な compiled dictionary export テストがLinux環境でも実行できるよう、テスト用の小さな charID.chid を注入できる形に修正しました。ただし最終的にはGitHub Actions上で確認する必要があるため、一度PRを出し、もし失敗した場合は追加修正します。 お手数をおかけしました。 |
目的
大きなユーザー辞書を使う場合に、変換時にすべての辞書項目を毎回動的辞書として組み立て直す負荷を減らします。
#318 で一度まとめて提案していた変更のうち、このPRでは「大規模ユーザー辞書を変換時に扱うためのcompiled dictionary利用」に範囲を絞っています。複数辞書管理、インポート / エクスポート、候補欄へのコメント表示は含めていません。
変更内容
意図
以前の実装では、変換のたびにユーザー辞書設定を読み出してdynamic dictionaryとして投入していたため、辞書が大きい場合に入力中の負荷が大きくなっていました。
今回の変更では、ユーザー辞書を設定したタイミングでexportし、変換時にはexport済みのcompiled dictionaryを利用する形に寄せています。これにより、変換中に重いexportや全件投入を行わずに済むようにしています。
候補数を上限で切るのではなく、辞書検索の入力経路をconverterが扱いやすい形式に寄せることで、変換候補の網羅性を落とさずに大規模辞書の負荷を下げる狙いです。
compiled dictionaryに含められない読みは捨てず、fallbackとして保持します。そのため、compiled dictionary対象外の項目も、入力中の読みと関係する場合は引き続き変換候補として出せます。
modificationDateは独自のrevision管理ではなく、実行中のIMEが設定変更後のcompiled dictionaryを再読み込みするための軽い更新検知として使っています。確認したこと
テスト